package com.qf.shop.search.service.impl;

import com.alibaba.fastjson.JSON;
import com.qf.shop.common.vo.GoodsVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.MatchAllQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class GoodsServiceImpl {

    @Autowired
    private RestHighLevelClient client;

    @Value("${es.index}")
    private String indexName;

    @Value("${es.type}")
    private String typeName;

    public void addGoods(String goodsVoJSON) throws IOException {
        // 4.插入
        IndexRequest request = new IndexRequest(indexName, typeName);
        request.source(goodsVoJSON, XContentType.JSON);
        IndexResponse index = client.index(request, RequestOptions.DEFAULT);
        System.out.println(index.getResult());
    }

    public List<Map<String, Object>> search(Map<String, Object> param) throws Exception {

        // 从Map中获取查询参数
        String keyword = (String) param.get("keyword"); // 关键字

        // 1.创建一个请求，设置索引，设置类型
        SearchRequest request = new SearchRequest(indexName);
        request.types(typeName);

        // 2.设置查询条件
        QueryBuilder queryBuilder = null;
        if (StringUtils.isEmpty(keyword)) {
            // 如果没有输入keyword就查询全部
            queryBuilder = QueryBuilders.matchAllQuery();
        } else {
            // gname或gdesc中出现关键字都可以匹配
            queryBuilder = QueryBuilders.multiMatchQuery(keyword, "gname", "gdesc");
        }

        // 3.设置查询条件条件
        SearchSourceBuilder source = request.source();
        source.query(queryBuilder);

        // 设置高亮的字段
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("gname");
        highlightBuilder.preTags("<font color='red'>");
        highlightBuilder.postTags("</font>");
        highlightBuilder.fragmentSize(10);
        source.highlighter(highlightBuilder);

        // 1:商品id,2:商品库存,3:价格升序，4：价格降序，不写按照匹配度来排序

        String psort = (String)param.get("psort"); // 获取排序字段
        if(!StringUtils.isEmpty(psort)){
            // 设置排序规则
            switch (psort) {
                case "1":
                    source.sort("id", SortOrder.ASC);
                    break;
                case "2":
                    source.sort("stock", SortOrder.DESC);
                    break;
                case "3":
                    source.sort("gprice", SortOrder.ASC);
                    break;
                case "4":
                    source.sort("gprice", SortOrder.DESC);
                    break;
            }
        }
        // 4.查询
        SearchResponse search = client.search(request, RequestOptions.DEFAULT);

        // 5.获取结果集
        List<Map<String, Object>> goodsMapList = new ArrayList<>();

        // 把search结果集封装到goodsVoList
        resoponceObject(search, goodsMapList);

        return goodsMapList;
    }

    private void resoponceObject(SearchResponse search, List<Map<String, Object>> goodsMapList) {

        // 1.获取结果集
        SearchHit[] hits = search.getHits().getHits();

        for (int i = 0; i < hits.length; i++) {
            // 把本次的商品信息转成一个Map
            Map<String, Object> sourceAsMap = hits[i].getSourceAsMap();

            // 判断当前商品是否有高亮字段
            Map<String, HighlightField> highlightFields = hits[i].getHighlightFields();
            if (!highlightFields.isEmpty() && highlightFields.get("gname") != null) {
                Text text = highlightFields.get("gname").getFragments()[0];
                String s = text.toString();
                sourceAsMap.put("gname", s);
            }
            goodsMapList.add(sourceAsMap);
        }
    }
}
